Load Packages and Data

Daten angucken

str(death)
'data.frame':   250 obs. of  4 variables:
 $ count   : int  3 2 1 1 4 2 2 2 3 2 ...
 $ geometry: chr  "<Point><coordinates>-0.13793,51.513418</coordinates></Point>" "<Point><coordinates>-0.137883,51.513361</coordinates></Point>" "<Point><coordinates>-0.137853,51.513317</coordinates></Point>" "<Point><coordinates>-0.137812,51.513262</coordinates></Point>" ...
 $ lon     : num  -0.138 -0.138 -0.138 -0.138 -0.138 ...
 $ lat     : num  51.5 51.5 51.5 51.5 51.5 ...
str(pump)
'data.frame':   8 obs. of  4 variables:
 $ count   : int  -999 -999 -999 -999 -999 -999 -999 -999
 $ geometry: chr  "<Point><coordinates>-0.136668,51.513341</coordinates></Point>" "<Point><coordinates>-0.139586,51.513876</coordinates></Point>" "<Point><coordinates>-0.139671,51.514906</coordinates></Point>" "<Point><coordinates>-0.13163,51.512354</coordinates></Point>" ...
 $ lon     : num  -0.137 -0.14 -0.14 -0.132 -0.134 ...
 $ lat     : num  51.5 51.5 51.5 51.5 51.5 ...

Get Maps

berlin.map <- get_map("Mitte, Berlin",
                        zoom = 16, 
                        maptype = "terrain", 
                        source = "stamen")

anzeigen lassen

# mit cowplot
plot_grid(plotlist = plots, ncol = 2, labels = c("Google Maps", "Stamen Maps", "Berlin Map"))
Fehler in plot_grid(plotlist = plots, ncol = 2, labels = c("Google Maps",  : 
  Objekt 'plots' nicht gefunden

weitere Layer hinzufügen

Adressen Geokodieren

home <- geocode(location = "Birkenstr. 11, Berlin", source = "google")
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Birkenstr.%2011%2C%20Berlin

Adresse zu Map hinzufügen

Shapefiles

bb.shp <- readOGR(dsn = "data/envvk9q3g/DE_BB_Mroad_Lnight.shp", layer = "DE_BB_Mroad_Lnight")
OGR data source with driver: ESRI Shapefile 
Source: "data/envvk9q3g/DE_BB_Mroad_Lnight.shp", layer: "DE_BB_Mroad_Lnight"
with 8117 features
It has 6 fields

1.Feb Maps II

germany <- get_map(location = "Germany",
                   zoom = 6,
                   maptype = "toner",
                   source = "stamen")
Source : https://maps.googleapis.com/maps/api/staticmap?center=Germany&zoom=6&size=640x640&scale=2&maptype=terrain
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Germany
geocode failed with status OVER_QUERY_LIMIT, location = "Germany"Fehler in data.frame(ll.lat = ll[1], ll.lon = ll[2], ur.lat = ur[1], ur.lon = ur[2]) : 
  arguments imply differing number of rows: 0, 1

Have a first look

Katre laden und als kontext Layer verwenden

# Stadtnamen ergänzen
city[c(3, 5, 6), "Hauptstadt"] <- c("Berlin", "Bremen", "Hamburg")
Fehler in city[c(3, 5, 6), "Hauptstadt"] <- c("Berlin", "Bremen", "Hamburg") : 
  Objekt 'city' nicht gefunden

Daten räumlich machen

# General logic for geocoding
geocode(location = "Stuttgart", output = "latlon", source = "google", inject = ", Germany")
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Stuttgart&,%20Germany

Für viele Städte

# for loop with if-condition for warnings
# run several times until no more NA's are returned
for(i in 1:nrow(city.df)) {
  if (is.na(city.df$lon[i])) {
    result <- tryCatch(geocode(city.df$Hauptstadt[i], output = "latlon", source = "google", inject = ", Germany"),
                       warning = function(x) data.frame(lon = NA, lat = NA))
    city.df$lon[i] <- as.numeric(result[1])
    city.df$lat[i] <- as.numeric(result[2])
  }
  i <- i + 1
  Sys.sleep(sample(seq(.5, 2, 0.5), 1))  
}
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Stuttgart&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=M%C3%BCnchen&, Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Berlin&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Potsdam&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Bremen&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Hamburg&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Wiesbaden&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Schwerin&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Hannover&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=D%C3%BCsseldorf&, Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Mainz&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Saarbr%C3%BCcken&, Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Dresden&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Magdeburg&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Kiel&,%20Germany
Source : https://maps.googleapis.com/maps/api/geocode/json?address=Erfurt&,%20Germany

Ausläneranteil darstellen

ger.map +
  geom_point(data = city.df, mapping = aes(x = lon, y = lat, size = Ausländeranteil), color = "gold2", alpha = .5)
Fehler in eval(expr, envir, enclos) : 
  Objekt 'Ausländeranteil' nicht gefunden

geht auch mit ggmap

bl.shp <- readOGR(dsn = "data/VG250_BL_2017",
                  use_iconv = TRUE, encoding = "UTF-8", stringsAsFactors = FALSE)
OGR data source with driver: ESRI Shapefile 
Source: "data/VG250_BL_2017", layer: "VG250_Bundesländergrenzen_2017"
with 35 features
It has 26 fields
Integer64 fields read as strings:  OBJECTID ADE GF BSG IBZ 

cleaning

# (2) ggfortify
bl.for <- fortify(bl.shp)
Regions defined for each Polygons

plot it

Shapefile angucken

using tmap

tm_shape(shp = bl.shp) +
  tm_polygons()

mergen

bl.shp <- sp::merge(bl.shp, city.df, by.x = "GEN", by.y = "Land")
Fehler in sp::merge(bl.shp, city.df, by.x = "GEN", by.y = "Land") : 
  Objekt 'city.df' nicht gefunden

TMap stellt daten zur Verfügung WHOOOOOP

LS0tCnRpdGxlOiAicnZpcyAxMyIKYXV0aG9yOiAiTGlzYSBSZWliZXIiCmRhdGU6ICIyNSAxIDIwMTgiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAojI0xvYWQgUGFja2FnZXMgYW5kIERhdGEKYGBge3IsIHJlc3VsdHM9RiwgbWVzc2FnZT1GLCBlY2hvPUZBTFNFfQojIyMjIGluc3RhbGwgbWlzc2luZyBwYWNrYWdlcyBhbmQgbG9hZCBuZWVkZWQgcGFja2FnZXMgIyMjIwojaW5zdGFsbC5wYWNrYWdlcygiZGV2dG9vbHMiKQojZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJka2FobGUvZ2dtYXAiKQpkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImhhZGxleS9nZ3Bsb3QyQHYyLjIuMCIpIAoKaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikKcGFjbWFuOjpwX2xvYWQoc3AsIHJnZGFsLCBnZ21hcCwgY293cGxvdCwgcnZlc3QsIHRtYXAsIHRpZHl2ZXJzZSApICAgICAgCgojIyMjIGxvYWQgZGF0YXNldCAjIyMjCmRlYXRoIDwtIHJlYWRSRFMoImRhdGEvRGVhdGgiKQpwdW1wIDwtIHJlYWRSRFMoImRhdGEvUHVtcCIpCmBgYAoKIyNEYXRlbiBhbmd1Y2tlbgpgYGB7cn0Kc3RyKGRlYXRoKQpzdHIocHVtcCkKYGBgCgojI0dldCBNYXBzCmBgYHtyfQojCnNub3cubWFwLmdnbCA8LSByZWFkUkRTKCJkYXRhL3Nub3dtYXBnZ2wiKQoKI0dvb2dsZSBNYXAKIyBzbm93Lm1hcC5nZ2wgPC0gZ2V0X21hcCgKICAgICAgIyAgICAgICAgICAgICBsb2NhdGlvbiA9ICJMb25kb24iLAogICAgICAjICAgICAgICAgICAgIHpvb20gPSAxNiwKICAgICAgIyAgICAgICAgICAgICAjIHdpZSBncm/DnyBzb2xsIGRlciBhdXNzY2huaXR0IHNlaW4/IDMgPSBLb250aW5lbnQgMjE9IGJ1aWxkaW5nCiAgICAgICMgICAgICAgICAgICAgc291cmNlID0gImdvb2dsZSIsCiAgICAgICMgICAgICAgICAgICAgbWFwdHlwZSA9ICJ0ZXJyYWluIgogICAgICAjICkKICAgICAgCiMgU3RhbWVuIE1hcApzbm93Lm1hcC5zdG0gPC0gZ2V0X21hcCgiU29obywgTG9uZG9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgem9vbSA9IDE2LCAKICAgICAgICAgICAgICAgICAgICAgICAgbWFwdHlwZSA9ICJ0ZXJyYWluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZSA9ICJzdGFtZW4iKQoKYmVybGluLm1hcCA8LSBnZXRfbWFwKCJNaXR0ZSwgQmVybGluIiwKICAgICAgICAgICAgICAgICAgICAgICAgem9vbSA9IDE2LCAKICAgICAgICAgICAgICAgICAgICAgICAgbWFwdHlwZSA9ICJ0ZXJyYWluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZSA9ICJzdGFtZW4iKQoKc25vdy5tYXAub3NtIDwtIGdldF9tYXAoIlNvaG8sIExvbmRvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHpvb20gPSAxNiwgCiAgICAgICAgICAgICAgICAgICAgICAgICNtYXB0eXBlID0gInRlcnJhaW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlID0gIm9zbSIpCgpiYi5tYXAgPC0gZ2V0X21hcCgiQnJhbmRlbmJ1cmciLAogICAgICAgICAgICAgICAgICAgICAgICB6b29tID0gNywgCiAgICAgICAgICAgICAgICAgICAgICAgIG1hcHR5cGUgPSAidGVycmFpbiIsIAogICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UgPSAic3RhbWVuIikKZ2dtYXAoc25vdy5tYXAuc3RtKQpgYGAKCiMjIGFuemVpZ2VuIGxhc3NlbgpgYGB7cn0KZ2cubWFwLmdnbCA8LSBnZ21hcChzbm93Lm1hcC5nZ2wpCmdnLm1hcC5zdG0gPC0gZ2dtYXAoc25vdy5tYXAuc3RtKQpnZy5tYXAuYnJsbiA8LSBnZ21hcChiZXJsaW4ubWFwKQpnZy5tYXAuYmIgICA8LSBnZ21hcChiYi5tYXApCgojIEtvbWJpbmllcmVuIHVuZCBwbG90dGVuIChjb3dwbG90KQpwbG90cyA8LSBsaXN0KGdnLm1hcC5nZ2wsIGdnLm1hcC5zdG0sIGdnLm1hcC5icmxuKSAKcGxvdHMKCiMgQ2xvdWRNYWRlIGV2dGwgaW50ZXJlc3NhbnQKCiMgbWl0IGNvd3Bsb3QKcGxvdF9ncmlkKHBsb3RsaXN0ID0gcGxvdHMsIG5jb2wgPSAyLCBsYWJlbHMgPSBjKCJHb29nbGUgTWFwcyIsICJTdGFtZW4gTWFwcyIsICJCZXJsaW4gTWFwIikpCmBgYAoKIyN3ZWl0ZXJlIExheWVyIGhpbnp1ZsO8Z2VuCmBgYHtyIEpvaG4gU25vdyBNYXB9CmdnLm1hcC5nZ2wgKyAgICAgICAgICAjIEJhc2lza2FydGUKICBnZW9tX3BvaW50KGRhdGEgPSBkZWF0aCwgYWVzKHggPSBsb24sIHkgPSBsYXQsIHNpemUgPSBjb3VudCksIAogICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsgICAjIExheWVyIGbDvHIgVG9kZXNmw6RsbGUKICBnZW9tX3BvaW50KGRhdGEgPSBwdW1wLCBhZXMoeCA9IGxvbiwgeSA9IGxhdCksIAogICAgICAgICAgICAgY29sb3IgPSAicmVkIiwgc3Ryb2tlID0gMywgc2hhcGUgPSA0LCBhbHBoYSA9IDAuNykgKyAgICMgTGF5ZXIgZsO8ciBQdW1wZW4KICB0aGVtZV92b2lkKCkgKyAgICAgICMgdGhlbWVfdm9pZCwgdW0gQWNoc2VuYmVzY2hyaWZ0dW5nIHp1IHZlcm1laWRlbgogIGxhYnModGl0bGUgPSAiUmVwcm9kdWN0aW9uIG9mIEpvaG4gU25vdydzIENob2xlcmEgTWFwIiwKICAgICAgIHNpemUgPSAiQ2hvbGVyYSBEZWF0aHMiLAogICAgICAgY2FwdGlvbiA9ICJEYXRhOiBodHRwczovL2Jsb2cucnR3aWxzb24uY29tL2pvaG4tc25vd3MtY2hvbGVyYS1kYXRhLWluLW1vcmUtZm9ybWF0cy8iKSAgICAgICAgICAgIyBUaXRlbCwgQ2FwdGlvbgpgYGAKIyMgQWRyZXNzZW4gR2Vva29kaWVyZW4KYGBge3J9CiMgUXVlcnkgbGltaXQgPSAyLDUwMCAoYSBkYXkpCklTVyA8LSBnZW9jb2RlKGxvY2F0aW9uID0gIlVuaXZlcnNpdGFldHNzdHIuIDNiLCBCZXJsaW4iLCBzb3VyY2UgPSAiZ29vZ2xlIikKaG9tZSA8LSBnZW9jb2RlKGxvY2F0aW9uID0gIkJpcmtlbnN0ci4gMTEsIEJlcmxpbiIsIHNvdXJjZSA9ICJnb29nbGUiKQojIFRoZSBvdGhlciB3YXkgYXJvdW5nCnJldmdlb2NvZGUobG9jYXRpb24gPSBjKElTVyRsb24sIElTVyRsYXQpLCBzb3VyY2UgPSAiZ29vZ2xlIiwgb3V0cHV0ID0gImFkZHJlc3MiKQpyZXZnZW9jb2RlKGxvY2F0aW9uID0gYyhob21lJGxvbiwgaG9tZSRsYXQpLCBzb3VyY2UgPSAiZ29vZ2xlIiwgb3V0cHV0ID0gImFkZHJlc3MiKQpgYGAKIAojIyBBZHJlc3NlIHp1IE1hcCBoaW56dWbDvGdlbgpgYGB7cn0KZ2cubWFwLmJybG4gKyAgICAgICAgICAjIEJhc2lza2FydGUKICBnZW9tX3BvaW50KGRhdGEgPSBob21lLCBhZXMoeCA9IGxvbiwgeSA9IGxhdCksIAogICAgICAgICAgICAgYWxwaGEgPSAwLjUsIHN0cm9rZSA9IDMpICsgICAjIExheWVyIGbDvHIgSG9tZQogCiAgdGhlbWVfdm9pZCgpICsgICAgICAjIHRoZW1lX3ZvaWQsIHVtIEFjaHNlbmJlc2NocmlmdHVuZyB6dSB2ZXJtZWlkZW4KICBsYWJzKHRpdGxlID0gIldobyBMaXZlcyBIZXJlPyIpICAgICAgICAgICAjIFRpdGVsLCBDYXB0aW9uCmBgYAoKIyMgU2hhcGVmaWxlcwpgYGB7cn0KbGlicmFyeShyZ2RhbCkKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShicm9vbSkKYmIuc2hwIDwtIHJlYWRPR1IoZHNuID0gImRhdGEvZW52dms5cTNnL0RFX0JCX01yb2FkX0xuaWdodC5zaHAiLCBsYXllciA9ICJERV9CQl9Ncm9hZF9MbmlnaHQiKQoKYmIuZnNocCA8LSB0aWR5KGJiLnNocCkKIApiYi5zaHBAcHJvajRzdHJpbmdAcHJvamFyZ3MKCiMgUGxvdCBtYXAgYW5kIG92ZXJsYXkgd2l0aCBzaGFwZWZpbGUKZ2dtYXAoYmIubWFwKSArCiAgZ2VvbV9wb2ludChkYXRhID0gYmIuZnNocCwgbWFwcGluZyA9IGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsdWUiLCBmaWxsID0gImJsYWNrIiwgYWxwaGEgPSAuNCkKYGBgCgojIyAxLkZlYiBNYXBzIElJCmBgYHtyfQpnZXJtYW55IDwtIGdldF9tYXAobG9jYXRpb24gPSAiR2VybWFueSIsCiAgICAgICAgICAgICAgICAgICB6b29tID0gNiwKICAgICAgICAgICAgICAgICAgIG1hcHR5cGUgPSAidG9uZXIiLAogICAgICAgICAgICAgICAgICAgc291cmNlID0gInN0YW1lbiIpCgpnZXJtYW55IDwtIHJlYWRSRFMoImRhdGEvR2VybWFuTWFwIikKYGBgCgpIYXZlIGEgZmlyc3QgbG9vawpgYGB7cn0KZ2VyLm1hcCA8LSBnZ21hcChnZXJtYW55KQpnZXIubWFwCmBgYAoKS2F0cmUgbGFkZW4gdW5kIGFscyBrb250ZXh0IExheWVyIHZlcndlbmRlbgpgYGB7cn0KIyBTY3JhcGVuCmNpdHkgPC0gcmVhZF9odG1sKCJodHRwczovL2RlLndpa2lwZWRpYS5vcmcvd2lraS9MYW5kXyhEZXV0c2NobGFuZCkiKSAlPiUKICBodG1sX25vZGVzKGNzcyA9ICJ0YWJsZS53aWtpdGFibGU6bnRoLWNoaWxkKDIyKSIpICU+JQogIGh0bWxfdGFibGUoKSAlPiUKICAuW1sxXV0gJT4lCiAgLlstMTcsLTFdCgojIFN0YWR0bmFtZW4gZXJnw6RuemVuCmNpdHlbYygzLCA1LCA2KSwgIkhhdXB0c3RhZHQiXSA8LSBjKCJCZXJsaW4iLCAiQnJlbWVuIiwgIkhhbWJ1cmciKQoKIyBEYXRlbiBpbiBudW1lcmlzY2hlIFdlcnRlIHVtd2FuZGVsbgpjaXR5LmRmIDwtIGNpdHkgJT4lCiAgbXV0YXRlX2F0KHZhcnMoYEVpbi13b2huZXIoTWlvLilbMTJdYCxgQXVzbMOkbmRlciglKVsxM11gICksCiAgICAgICAgICAgIC5mdW5zID0gZnVucyhhcy5udW1lcmljKHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChzdHJpbmcgPSAuLCBwYXR0ZXJuID0gIiwiLCByZXBsYWNlbWVudCA9ICJcXC4iKSkpKQoKIyBWYXJpYWJsZW5uYW1lbgpjb2xuYW1lcyhjaXR5LmRmKSA8LSBjKCJMYW5kIiwgIkvDvHJ6ZWwiLCAiSGF1cHRzdGFkdCIsICJCZWl0cml0dCIsICJSZWdpZXJ1bmciLCAiUGFydGVpZW4iLAogICAgICAgICAgICAgICAgICAgICAgICJTdGltbWVuIiwgIkZsw6RjaGUiLCAiRWlud29obmVyIiwgIkVpbndEaWNodGUiLCAiQXVzbMOkbmRlcmFudGVpbCIsICJTcHJhY2hlbiIpCgoKYGBgCgpEYXRlbiByw6R1bWxpY2ggbWFjaGVuCmBgYHtyfQojIEdlbmVyYWwgbG9naWMgZm9yIGdlb2NvZGluZwpnZW9jb2RlKGxvY2F0aW9uID0gIlN0dXR0Z2FydCIsIG91dHB1dCA9ICJsYXRsb24iLCBzb3VyY2UgPSAiZ29vZ2xlIiwgaW5qZWN0ID0gIiwgR2VybWFueSIpCmBgYAoKRsO8ciB2aWVsZSBTdMOkZHRlCmBgYHtyfQojIFVtIG5pY2h0IMO8YmVyIGRhcyBxdWVyeSBsaW1pdCB6dSBrb21tZW4sIG5laG10IGxpZWJlciBkZW4gRGF0ZW5zYXR6IGF1cyBkZW0gS3VycwoKIyBXcmFwIGludG8gYSBsb29wCiMgQ3JlYXRlIHZhcmlhYmxlcyBiZWZvcmVoYW5kCmNpdHkuZGYkbG9uIDwtIE5BCmNpdHkuZGYkbGF0IDwtIE5BCgojIGZvciBsb29wIHdpdGggaWYtY29uZGl0aW9uIGZvciB3YXJuaW5ncwojIHJ1biBzZXZlcmFsIHRpbWVzIHVudGlsIG5vIG1vcmUgTkEncyBhcmUgcmV0dXJuZWQKZm9yKGkgaW4gMTpucm93KGNpdHkuZGYpKSB7CiAgaWYgKGlzLm5hKGNpdHkuZGYkbG9uW2ldKSkgewogICAgcmVzdWx0IDwtIHRyeUNhdGNoKGdlb2NvZGUoY2l0eS5kZiRIYXVwdHN0YWR0W2ldLCBvdXRwdXQgPSAibGF0bG9uIiwgc291cmNlID0gImdvb2dsZSIsIGluamVjdCA9ICIsIEdlcm1hbnkiKSwKICAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gZnVuY3Rpb24oeCkgZGF0YS5mcmFtZShsb24gPSBOQSwgbGF0ID0gTkEpKQogICAgY2l0eS5kZiRsb25baV0gPC0gYXMubnVtZXJpYyhyZXN1bHRbMV0pCiAgICBjaXR5LmRmJGxhdFtpXSA8LSBhcy5udW1lcmljKHJlc3VsdFsyXSkKICB9CiAgaSA8LSBpICsgMQogIFN5cy5zbGVlcChzYW1wbGUoc2VxKC41LCAyLCAwLjUpLCAxKSkgIAp9CmBgYAoKQXVzbMOkbmVyYW50ZWlsIGRhcnN0ZWxsZW4gCmBgYHtyfQpnZXIubWFwICsKICBnZW9tX3BvaW50KGRhdGEgPSBjaXR5LmRmLCBtYXBwaW5nID0gYWVzKHggPSBsb24sIHkgPSBsYXQsIHNpemUgPSBBdXNsw6RuZGVyYW50ZWlsKSwgY29sb3IgPSAiZ29sZDIiLCBhbHBoYSA9IC41KQoKYGBgCmdlaHQgYXVjaCBtaXQgZ2dtYXAKYGBge3J9CmJsLnNocCA8LSByZWFkT0dSKGRzbiA9ICJkYXRhL1ZHMjUwX0JMXzIwMTciLAogICAgICAgICAgICAgICAgICB1c2VfaWNvbnYgPSBUUlVFLCBlbmNvZGluZyA9ICJVVEYtOCIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKYGBgCmNsZWFuaW5nCmBgYHtyfQojIFp3ZWkgQnVuZGVzbMOkbmRlciB1bWJlbm5lbiAoZsO8ciBzcMOkdGVyKQpibC5zaHBAZGF0YSRHRU5bYmwuc2hwQGRhdGEkR0VOID09ICJCYWRlbi1Xw7xydHRlbWJlcmcgKEJvZGVuc2VlKSJdIDwtICJCYWRlbi1Xw7xydHRlbWJlcmciCmJsLnNocEBkYXRhJEdFTltibC5zaHBAZGF0YSRHRU4gPT0gIkJheWVybiAoQm9kZW5zZWUpIl0gPC0gIkJheWVybiIKCiMgKDIpIGdnZm9ydGlmeQpibC5mb3IgPC0gZm9ydGlmeShibC5zaHApCmBgYAogcGxvdCBpdApgYGB7cn0KZ2VyLm1hcCArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBibC5mb3IsIG1hcHBpbmcgPSBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGZpbGwgPSBpZCksCiAgICAgICAgICAgICAgIGNvbG9yID0gImJsdWUiLCBmaWxsID0gImJsYWNrIiwgYWxwaGEgPSAuNCkKCnBsb3QoYmwuc2hwICkKYGBgCiAKClNoYXBlZmlsZSBhbmd1Y2tlbgpgYGB7cn0KdHlwZW9mKGJsLnNocCkKCmNsYXNzKGJsLnNocCkKCnN0cihibC5zaHAsIG1heC5sZXZlbCA9IDIpICMgdXNlZnVsIGFyZ3M6IG1heC5sZXZlbCAmIGxpc3QubGVuCnN0cihibC5zaHBAZGF0YSwgbWF4LmxldmVsID0gMiwgbGlzdC5sZW4gPSAzKQpzdHIoYmwuc2hwQHBvbHlnb25zLCBtYXgubGV2ZWwgPSAyLCBsaXN0LmxlbiA9IDMpCnN0cihibC5zaHBAcGxvdE9yZGVyKQpzdHIoYmwuc2hwQGJib3gpCnN0cihibC5zaHBAcHJvajRzdHJpbmcpICMgaHR0cDovL3Byb2o0Lm9yZy9wcm9qZWN0aW9ucy9pbmRleC5odG1sCmxpc3R2aWV3ZXI6Ompzb25lZGl0KGJsLnNocCkKYGBgCgoKCnVzaW5nIHRtYXAgCmBgYHtyfQpsaWJyYXJ5KHRtYXApCnRtX3NoYXBlKHNocCA9IGJsLnNocCkgKwogIHRtX3BvbHlnb25zKCkKCgoKYGBgCm1lcmdlbgpgYGB7cn0KYmwuc2hwIDwtIHNwOjptZXJnZShibC5zaHAsIGNpdHkuZGYsIGJ5LnggPSAiR0VOIiwgYnkueSA9ICJMYW5kIikKCiMgQXVjaCBTZWVnZWJpZXRlIGVudGZlcm5lbiAoaW5kZXhpbmcpCmJsLnNocCA8LSBibC5zaHBbYmwuc2hwQGRhdGEkR0YgIT0gMSxdIAoKYGBgCgpUTWFwIHN0ZWxsdCBkYXRlbiB6dXIgVmVyZsO8Z3VuZwpXSE9PT09PUApgYGB7cn0KZGF0YShFdXJvcGUpCgpnbGltcHNlKEV1cm9wZUBkYXRhKQoKdG1fc2hhcGUoRXVyb3BlKSsKICAgICAgdG1fcG9seWdvbnMoY29sID0gImdkcF9jYXBfZXN0Iiwgc3R5bGUgPSAicXVhbnRpbGUiKQpgYGAKCgoKCgoKCg==